package com.tevintao.marketingsystem.task;

import android.content.Context;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.view.View;

import com.tevintao.marketingsystem.activity.MainActivity;
import com.tevintao.marketingsystem.log.LogManager;
import com.tevintao.marketingsystem.services.MockServices;
import com.tevintao.marketingsystem.tool.PackageTool;
import com.tevintao.marketingsystem.xposted.HookDeviceModule;
import com.tevintao.marketingsystem.xposted.HookWindowManagerGlobal;
import com.tevintao.marketingsystem.xposted.WxTaskManger;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class WxTaskProcess {

    public static final boolean DEBUG_MODEL = false;//BuildConfig.DEBUG;
    public static final int TASK_ID_BASE = 0;
    public static final int TASK_ID_BROW_FRIEND_CIRCLE = 1; //浏览朋友圈
    public static final int TASK_ID_STATISTICS_FRIEND_NUM = 2;//统计好友数量
    public static final int TASK_ID_ACCEPT_NEARBY_FRIEND = 3;//接受附近人好友
    public static final int TASK_ID_FRIEND_AGREE = 4;//朋友圈点赞
    public static final int TASK_ID_FRIEND_COMMENT = 5;//朋友圈评论
    public static final int TASK_ID_ADD_FRIEND = 6;//通过搜索号码添加自己人好友
    public static final int TASK_ID_ACCEPT_FRIEND = 7;//接受自己人搜索添加的好友
    public static final int TASK_ID_SELF_CHAT = 8;//自己人聊天
    public static final int TASK_ID_ACCEPT_ALL_FRIEND_REQUEST = 9;//接受所有好友请求，不区分来源。
    public static final int TASK_ID_GET_NICK_NAME = 10;//获取昵称
    public static final int TASK_ID_ADD_NEARBY_FRIEND = 11;//添加附近人
    public static final int TASK_ID_FORWARD_SUBSCRIBE = 12;//转发订阅号中的内容到朋友圈
    public static final int TASK_ID_SEND_FRIEND_CIRCLE = 13;//发送朋友圈原创内容
    public static final int TASK_ID_SHAKE_SHAKE = 14;//摇一摇
    public static final int TASK_ID_ADD_CONTACTS_FRIEND = 15;//上报通讯录
    public static final int TASK_ID_ADD_SUBSCRIBE = 16;//添加订阅号
    public static final int TASK_ID_WAIT = 17;//帐号等待
    public static final int TASK_CHANGE_SEX = 18;//更换性别
    public static final int TASK_CHANGE_SIGNATURE = 19;//更换签名
    public static final int TASK_CHANGE_ICON = 20;//更换个人头像
    public static final int TASK_CHANGE_FRIEND_BACK = 21;//更换朋友圈背景
    public static final int TASK_ID_BUSINESS_CHECK = 22;//微商版聊天记录检测
    public static final int TASK_ID_AUTO_REGISTER = 23;//自动注册
    public static final int TASK_ID_READ_NEW_MESSAGE = 24;//自动阅读新消息
    public static final int TASK_ID_ADD_SEARCH_CONTACTS_FRIEND = 25;//添加通过搜索号码添加朋友
    public static final int TASK_ID_ADD_RECOMMEND_CONTACTS_FRIEND = 26;//添加一个推荐好友，90%是通讯录推荐
    public static final int TASK_ID_REPORT_ICON_FRIEND = 27;//上报图像

    private Map<Integer, SetTaskExtra> mTaskMap = new HashMap<>();
    private Map<Integer, Object> mDebugTaskMap = new HashMap<>();


    private static WxTaskProcess ourInstance = null;

    public static WxTaskProcess getInstance() {
        if (ourInstance == null) {
            synchronized (WxTaskProcess.class) {
                if (ourInstance == null) {
                    ourInstance = new WxTaskProcess();
                }
            }
        }
        return ourInstance;
    }

    private WxTaskProcess() {
        mTaskMap.put(TASK_ID_BASE, BaseTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_BROW_FRIEND_CIRCLE, BrowFriendTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_STATISTICS_FRIEND_NUM, StatisticsFriendNumTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_ACCEPT_NEARBY_FRIEND, AcceptNearbyFriendTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_FRIEND_AGREE, FriendAgreeTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_FRIEND_COMMENT, FriendCommentTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_ADD_FRIEND, AddFriendBySearchTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_ACCEPT_FRIEND, AcceptSearchFriendTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_SELF_CHAT, ChatSelfFriendTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_ACCEPT_ALL_FRIEND_REQUEST, AcceptAllFriendTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_GET_NICK_NAME, GetNickNameTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_ADD_NEARBY_FRIEND, AddNearbyFriendTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_FORWARD_SUBSCRIBE, ForwardSubscribeTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_SEND_FRIEND_CIRCLE, SendFriendCircleTaskProcess.getInstance());

        mTaskMap.put(TASK_ID_SHAKE_SHAKE, ShakeShakeProcess.getInstance());
        mTaskMap.put(TASK_ID_ADD_CONTACTS_FRIEND, UploadContactsProcess.getInstance());
        mTaskMap.put(TASK_ID_ADD_SUBSCRIBE, AddSubscribeProcess.getInstance());
        mTaskMap.put(TASK_ID_WAIT, WaitProcess.getInstance());


        mTaskMap.put(TASK_CHANGE_SEX, ChangeSexTaskProcess.getInstance());
        mTaskMap.put(TASK_CHANGE_SIGNATURE, ChangeSignatureTaskProcess.getInstance());
        mTaskMap.put(TASK_CHANGE_ICON, ChangeIconTaskProcess.getInstance());
        mTaskMap.put(TASK_CHANGE_FRIEND_BACK, ChangeFriendCircleBackgroundTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_BUSINESS_CHECK, BussinessCheckTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_AUTO_REGISTER, AutoRegisterTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_READ_NEW_MESSAGE, ReadNewMessageProcess.getInstance());

        mTaskMap.put(TASK_ID_ADD_SEARCH_CONTACTS_FRIEND, SearchContactsFriendProcess.getInstance());
        mTaskMap.put(TASK_ID_ADD_RECOMMEND_CONTACTS_FRIEND, AddRecommendFriendTaskProcess.getInstance());
        mTaskMap.put(TASK_ID_REPORT_ICON_FRIEND, ReportIconTaskProcess.getInstance());
    }


    public boolean processView() {
        if (WxTaskManger.getInstance().getTaskId() == TASK_ID_WAIT) {
            LogManager.getInstance().logInfo("等待任务，需要休息");
            return true;
        }
        View topView = HookWindowManagerGlobal.getInstance().getTopView();
        if (null == topView) {
//            LogManager.getInstance().logError("topView = null  getProcessName = " + MockServices.getProcessName());
            if ("com.tencent.mm".equals(MockServices.getProcessName())) {
                List<View> views = MainActivity.pirntView();
                LogManager.getInstance().logError("views = " + views);
            }
            return false;
        } else {
//            LogManager.getInstance().logError("topView != null  getProcessName = " + MockServices.getProcessName() + "topView " + topView + " topView.getContext() = " + topView.getContext());
        }
        Context context = topView.getContext();
        if (null == context) {
            LogManager.getInstance().logError("null == topView.getContext()");
            return false;
        }
        String contextName = context.getClass().getName();
        String topActName = PackageTool.getTopActivityName(context);
//        String topPackageName = PackageTool.getTopPackageName(context);
//        LogManager.getInstance().logInfo("topPackageName = " + topPackageName + " contextName = " + contextName + " topActName = " + topActName + " ProcessName " + MockServices.getProcessName());
        //处理View的两个条件，1，是dialog 2，顶层activity一直，
        LogManager.getInstance().logInfo("WxTaskProcess " + MockServices.getProcessName() + " contextName = " + contextName + " topActName = " + topActName);
        if ((WxUiViewConfig.DIALOG_CLASS.equals(contextName) ) || (!TextUtils.isEmpty(topActName) && topActName.equals(contextName))) {
            if (DEBUG_MODEL) {
                return debugProcessViewLogic(contextName, topView);
            } else {
                return processViewLogic(contextName, topView);
            }
        } else {
            return false;
        }
    }

    public boolean debugProcessViewLogic(String contextName, View v) {
        Object baseTask = getTaskProcess(v.getContext(), TASK_ID_BASE);
//        LogManager.getInstance().logInfo("debugProcessViewLogic baseTask = " + baseTask);
        if (null != baseTask) {
            try {
                Method setExtraMethod = baseTask.getClass().getSuperclass().getDeclaredMethod("setExtra", Map.class);
                /*boolean setExtra = (boolean) */
                setExtraMethod.invoke(baseTask, WxTaskManger.getInstance().getExtraMap());
//                LogManager.getInstance().logInfo("debugProcessViewLogic baseTask setExtra = " + setExtra);

                Method processMethod = baseTask.getClass().getDeclaredMethod("processView", String.class, View.class);
                Object success = processMethod.invoke(baseTask, contextName, v);
                if (success instanceof Boolean) {
                    boolean returnState = (boolean) success;
                    if (returnState) {
                        return true;
                    }
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
                LogManager.getInstance().logError("debugProcessViewLogic baseTask NoSuchMethodException " + e.toString());
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                LogManager.getInstance().logError("debugProcessViewLogic baseTask NoSuchMethodException " + e.toString());
                LogManager.getInstance().logErrorAndPrint("debugProcessViewLogic baseTask InvocationTargetException " + e.toString(), e);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                LogManager.getInstance().logError("debugProcessViewLogic baseTask IllegalAccessException " + e.toString());
            } catch (Exception e) {
                e.printStackTrace();
                LogManager.getInstance().logError("debugProcessViewLogic baseTask Exception " + e.toString());
            }

            int currentTaskId = WxTaskManger.getInstance().getTaskId();
//            LogManager.getInstance().logInfo("debugProcessViewLogic WxTaskManger.getInstance().getTaskId() = " + currentTaskId);
            if (currentTaskId > 0) {
                Object taskProcess = getTaskProcess(v.getContext(), currentTaskId);
//                LogManager.getInstance().logInfo("debugProcessViewLogic taskProcess = " + taskProcess);
                if (null != taskProcess) {
                    try {
                        Method setExtraMethod = taskProcess.getClass().getSuperclass().getDeclaredMethod("setExtra", Map.class);
                        /*boolean setExtra = (boolean) */
                        setExtraMethod.invoke(taskProcess, WxTaskManger.getInstance().getExtraMap());
//                        LogManager.getInstance().logInfo("debugProcessViewLogic taskProcess setExtra = " + setExtra);

                        Method processMethod = taskProcess.getClass().getDeclaredMethod("processView", String.class, View.class);
                        Object success = processMethod.invoke(taskProcess, contextName, v);
                        if (success instanceof Boolean) {
                            boolean returnState = (boolean) success;
                            if (returnState) {
                                return true;
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                        LogManager.getInstance().logError("debugProcessViewLogic taskProcess NoSuchMethodException " + e.toString());
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                        LogManager.getInstance().logError("debugProcessViewLogic taskProcess InvocationTargetException " + e.toString());
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                        LogManager.getInstance().logError("debugProcessViewLogic taskProcess IllegalAccessException " + e.toString());
                    } catch (Exception e) {
                        e.printStackTrace();
                        LogManager.getInstance().logError("debugProcessViewLogic taskProcess Exception " + e.toString());
                    }
                    return false;
                } else {
                    LogManager.getInstance().logError("没有找到对应任务");
                    return false;
                }
            } else {
                LogManager.getInstance().logError("获取到执行的任务id 小于0");
            }
        }
        return false;
    }


    private boolean processViewLogic(String contextName, View v) {
        BaseTaskProcess baseTaskProcess = BaseTaskProcess.getInstance();

        boolean processBaseView = baseTaskProcess.processView(contextName, v);
        if (processBaseView) {
            LogManager.getInstance().logInfo("BaseTaskProcess return true");
            return true;//处理完毕，不需要其他任务来处理
        }

        int currentTaskId = WxTaskManger.getInstance().getTaskId();
        if (currentTaskId > 0) {
            SetTaskExtra process = mTaskMap.get(currentTaskId);
            if (null != process) {
                return process.processView(contextName, v);
            } else {
                LogManager.getInstance().logError("没有找到对应任务");
                return false;
            }
        } else {
            LogManager.getInstance().logError("获取到执行的任务id 小于0");
        }
        return false;
    }


    private Context mMarkSystemContext = null;

    public Class getTaskClass(Context context, String name) {
        if (null == mMarkSystemContext) {
            try {
                mMarkSystemContext = context.createPackageContext(HookDeviceModule.SELF_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
                LogManager.getInstance().logError("getTaskClass PackageManager.NameNotFoundException");
            }
        }
        if (null == mMarkSystemContext) {
            LogManager.getInstance().logError("null == mMarkSystemContext");
            return null;
        }

        try {
            return mMarkSystemContext.getClassLoader().loadClass(name);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            LogManager.getInstance().logError("getTaskClass ClassNotFoundException name = " + name);
        }
        return null;
    }

    public Object getTaskProcess(Context context, int id) {
        if (mDebugTaskMap.containsKey(id) && id != WxTaskProcess.TASK_ID_FORWARD_SUBSCRIBE && id != WxTaskProcess.TASK_ID_STATISTICS_FRIEND_NUM) {
            return mDebugTaskMap.get(id);
        }

        SetTaskExtra process = mTaskMap.get(id);
        if (null == process) {
            return null;
        } else {
            Class taskClass = getTaskClass(context, process.getClass().getName());
            LogManager.getInstance().logInfo("getTaskProcess taskClass = " + taskClass);
            if (null != taskClass) {
                try {
                    Field field = taskClass.getDeclaredField("ourInstance");
                    field.setAccessible(true);
                    Object obj = field.get(null);
                    mDebugTaskMap.put(id, obj);
                    return obj;
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                    LogManager.getInstance().logError("getTaskProcess id = " + id + " NoSuchMethodException " + e.toString());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    LogManager.getInstance().logError("getTaskProcess id = " + id + " IllegalAccessException " + e.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                    LogManager.getInstance().logError("getTaskProcess id = " + id + " Exception " + e.toString());

                }
            }
        }
        return null;
    }
}
